package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.exception.BizException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.db.entity.WarnStrategy;
import com.mingqijia.gassafety.db.entity.WarnStrategyCheck;
import com.mingqijia.gassafety.db.entity.vo.WarnStrategyCheckParamVO;
import com.mingqijia.gassafety.db.entity.vo.WarnStrategyCheckVO;
import com.mingqijia.gassafety.db.mapper.ConsumerMapper;
import com.mingqijia.gassafety.db.mapper.WarnStrategyCheckMapper;
import com.mingqijia.gassafety.db.mapper.WarnStrategyMapper;
import com.mingqijia.gassafety.db.mapper.WarningRecordMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import com.mingqijia.gassafety.webserver.request.*;
import com.mingqijia.gassafety.webserver.request.SaveWarnStrategyRequest;
import com.mingqijia.gassafety.webserver.service.UserService;
import com.mingqijia.gassafety.webserver.service.WarnStrategyCheckService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.validation.Valid;
import java.util.*;

/**
 * <p>
 * 报警策略审核表 服务实现类
 * </p>
 *
 * @author wanghai
 * @since 2022-06-21
 */
@Service
@Slf4j
public class WarnStrategyCheckServiceImpl extends ServiceImpl<WarnStrategyCheckMapper, WarnStrategyCheck> implements WarnStrategyCheckService {

    public static final String format = "yyyy-MM-dd HH:mm:ss";
    public static final String split = ";";

    @Autowired
    private WarnStrategyCheckMapper warnStrategyCheckMapper;
    @Autowired
    private WarnStrategyMapper warnStrategyMapper;
    @Autowired
    private WarningRecordMapper warningRecordMapper;
    @Autowired
    WarnStrategyServiceImpl warnStrategyService;
    @Autowired
    VccAuthoritiesProvider vccAuthoritiesProvider;
    @Autowired
    EquipmentServiceImpl equipmentService;
    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    UserService userService;

    @Override
    public PageUtil<WarnStrategyCheck> getCheckList(WarnStrategyCheckListRequest request) {
        LambdaQueryWrapper<WarnStrategyCheck> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarnStrategyCheck::getIsDeleted, 0)
                .orderByDesc(WarnStrategyCheck::getApplicationTime);
        if (request.getSpIds() != null) {
            queryWrapper.in(WarnStrategyCheck::getSpId, request.getSpIds());
        } else {
            List<String> spIds = new ArrayList<>();
            String spId = ApplicationUtils.getWorkingSpId();
            spIds.add(spId);
            //查询子公司spId
            cn.hutool.json.JSONObject jsonObject = getChildSpId(spId);
            JSONArray array = jsonObject.getJSONArray("items");
            if (array != null) {
                for (Object o : array) {
                    cn.hutool.json.JSONObject json = (cn.hutool.json.JSONObject) o;
                    spIds.add(json.get("spId").toString());
                }
            }
            queryWrapper.in(WarnStrategyCheck::getSpId, spIds);
        }
        if (!StringUtils.isEmpty(request.getSubmitPersonPhone())) {
            queryWrapper.like(WarnStrategyCheck::getSubmitPersonPhone, request.getSubmitPersonPhone());
        }
        if (!StringUtils.isEmpty(request.getRuleName())) {
            queryWrapper.like(WarnStrategyCheck::getRuleName, request.getRuleName());
        }
        if (request.getCheckStatus() != null) {
            queryWrapper.eq(WarnStrategyCheck::getCheckStatus, request.getCheckStatus());
        }
        if (!StringUtils.isEmpty(request.getApplicationStartTime()) && !StringUtils.isEmpty(request.getApplicationEndTime())) {
            queryWrapper.ge(WarnStrategyCheck::getApplicationTime, request.getApplicationStartTime())
                    .le(WarnStrategyCheck::getApplicationTime, request.getApplicationEndTime());
        }
        if (!StringUtils.isEmpty(request.getCheckStartTime()) && !StringUtils.isEmpty(request.getCheckEndTime())) {
            queryWrapper.ge(WarnStrategyCheck::getCheckTime, request.getCheckStartTime())
                    .le(WarnStrategyCheck::getCheckTime, request.getCheckEndTime());
        }
        Page pageHelper = PageHelper.startPage(request.getPage(), request.getPageSize());
        List<WarnStrategyCheck> list = this.list(queryWrapper);

        PageUtil<WarnStrategyCheck> pageInfo = new PageUtil(request.getPage(), request.getPageSize(), pageHelper.getTotal(), list);
        return pageInfo;
    }

    @Override
    public void cancel(Long id) {
        WarnStrategyCheck check = this.getById(id);
        if (check != null) {
            //待审核状态才可以取消
            if (check.getCheckStatus().equals(0)) {
                WarnStrategyCheck record = new WarnStrategyCheck();
                record.setId(id);
                //取消
                record.setCheckStatus(3);
                this.updateById(record);
            }
        }
    }

    /**
     * 策略审核
     *
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void strategyCheck(@Valid StrategyCheckRequest request) {
        WarnStrategyCheck warnStrategyCheck = warnStrategyCheckMapper.selectById(request.getId());
        if (warnStrategyCheck == null || warnStrategyCheck.getId() == null) {
            throw new BizException("数据不存在");
        }
        if (warnStrategyCheck.getCheckStatus() != 0) {
            throw new BizException("只能审批待审核中的申请记录");
        }
        WarnStrategyCheck check = new WarnStrategyCheck();
        check.setId(request.getId());
        check.setCheckStatus(request.getCheckStatus());
        check.setRemark(request.getRemark());
        check.setCheckPersonCode(ApplicationUtils.getWorkingUser().getUsername());
        check.setCheckPersonName(ApplicationUtils.getWorkingUser().getName());
        check.setCheckTime(DateUtil.format(new Date(), format));
        warnStrategyCheckMapper.updateById(check);
        if (request.getCheckStatus() == 2) {
            String ruleJsonData = warnStrategyCheck.getRuleJsonData();
            if (StringUtils.isEmpty(ruleJsonData)) {
                throw new BizException("审核失败");
            }
            SaveWarnStrategyRequest saveWarnStrategyRequest =
                    JSONObject.parseObject(warnStrategyCheck.getRuleJsonData(), SaveWarnStrategyRequest.class);
            saveWarnStrategyRequest.setSaveAndEnable(0);
            saveWarnStrategyRequest.setSpId(warnStrategyCheck.getSpId());
            if (warnStrategyCheck.getRuleId() == null || warnStrategyCheck.getRuleId() == 0) {
                warnStrategyService.saveWarnStrategy(saveWarnStrategyRequest, 1);
            } else {
                warnStrategyService.editWarnStrategy(saveWarnStrategyRequest, 1);
            }
        }
    }

    @Override
    public PageUtil<WarnStrategyCheck> getPetitionList(WarnStrategyPetitionListRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<WarnStrategyCheck> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarnStrategyCheck::getIsDeleted, 0)
                .eq(WarnStrategyCheck::getSpId, spId)
                .orderByDesc(WarnStrategyCheck::getApplicationTime);
        if (!StringUtils.isEmpty(request.getRuleName())) {
            queryWrapper.like(WarnStrategyCheck::getRuleName, request.getRuleName());
        }
        if (request.getStrategyObj() != null) {
            queryWrapper.eq(WarnStrategyCheck::getStrategyObj, request.getStrategyObj());
        }
        if (!StringUtils.isEmpty(request.getApplicationStartTime()) && !StringUtils.isEmpty(request.getApplicationEndTime())) {
            queryWrapper.ge(WarnStrategyCheck::getApplicationTime, request.getApplicationStartTime())
                    .le(WarnStrategyCheck::getApplicationTime, request.getApplicationEndTime());
        }
        if (request.getCheckStatus() != null) {
            queryWrapper.eq(WarnStrategyCheck::getCheckStatus, request.getCheckStatus());
        }
        List<String> splits = new ArrayList<>();
        if (request.getStrategyObj() != null) {
            String objValues = request.getStrategyObjValues();
            if (!StringUtils.isEmpty(objValues)
                    && objValues.contains(split)) {
                splits = new ArrayList<>(Arrays.asList(objValues.split(WarnStrategyServiceImpl.split)));
                for (int i = 0; i < splits.size(); i++) {
                    if (i == 0) {
                        queryWrapper.like(WarnStrategyCheck::getStrategyObjValues, splits.get(i));
                    } else {
                        queryWrapper.or().like(WarnStrategyCheck::getStrategyObjValues, splits.get(i));
                    }
                }
            } else if (!StringUtils.isEmpty(objValues)) {
                queryWrapper.eq(WarnStrategyCheck::getStrategyObjValues, objValues + ";");
            }
        }
        Page pageHelper = PageHelper.startPage(request.getPage(), request.getPageSize());
        List<WarnStrategyCheck> list = this.list(queryWrapper);
        List<WarnStrategyCheck> resList = new ArrayList<>();
        for (WarnStrategyCheck check : list) {
            String objValues = check.getStrategyObjValues();
            if (!"0".equals(request.getStrategyObj()) && !StringUtils.isEmpty(request.getStrategyObjValues())
                    && request.getStrategyObjValues().contains(split)) {
                //行业和客户选择的情况下
                int i = 0;
                String[] split = objValues.split(WarnStrategyServiceImpl.split);
                for (String objValue : splits) {
                    if (new ArrayList<>(Arrays.asList(split)).contains(objValue)) {
                        i = 1;
                        continue;
                    }
                }
                if (i == 0) {
                    continue;
                }
            }
            resList.add(check);

        }
        //进行转换
        resList.forEach(warn -> {
            //根据客户id获取客户名称、行业名称
            String values = "";
            String strategyObjValues = warn.getStrategyObjValues();
            if (!StringUtils.isEmpty(strategyObjValues)
                    && strategyObjValues.contains(split)) {

                String[] r = strategyObjValues.split(WarnStrategyServiceImpl.split);
                if (r.length > 0) {
                    if (warn.getStrategyObj() == 1) {
                        //按照行业选择
                        List<Map<String, String>> industryType = equipmentService
                                .dictMap("Industry_type", null, spId);
                        if (!CollectionUtil.isEmpty(industryType)) {
                            for (String s : r) {
                                for (Map<String, String> map : industryType) {
                                    if (map.get("value").equals(s)) {
                                        values = map.get("alias") + "、" + values;
                                    }
                                }
                            }

                        }
                        if (values.length() > 0) values = values.substring(0, values.length() - 1);
                    } else {
                        //按照客户选择
                        values = consumerMapper.selectNames(spId, r);
                    }
                }
            }
            warn.setStrategyObjValues(values);

        });

        PageUtil<WarnStrategyCheck> pageInfo = new PageUtil(request.getPage(), request.getPageSize(), pageHelper.getTotal(), resList);
        return pageInfo;
    }

    @Override
    public void resubmit(SaveWarnStrategyRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        if (request.getCheckId() == null) {
            throw new BizException("checkId为必传字段");
        }
        // 进行校验, 可能是新策略,没有id
        if (request.getStrategyObj() != 0 &&
                !StringUtils.isEmpty(request.getStrategyObjValues())) {
            request.setStrategyObjValues(request.getStrategyObjValues() + split);
        }
        if (request.getId() != null) {
            WarnStrategy warn = warnStrategyMapper.selectWarnStrategyById(request.getId());
            if (warn == null) throw new BizException("数据不存在或已失效");
            if (warn.getIsDisabled() == 0) {
                //校验规则是否在使用
                int count = warningRecordMapper.selectWarnStrategyUse(request.getId());
                if (count > 0) throw new BizException("执行中的策略不可编辑");
            }

            //判断该规则  非取消审核状态
            QueryWrapper<WarnStrategyCheck> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(WarnStrategyCheck::getId, request.getCheckId())
                    .eq(WarnStrategyCheck::getRuleId, request.getId())
                    .eq(WarnStrategyCheck::getIsDeleted, Constants.IS_DELETED_FALSE)
                    .ne(WarnStrategyCheck::getCheckStatus, 1) // 非取消审核状态
                    .eq(WarnStrategyCheck::getSpId, spId);
            List<WarnStrategyCheck> checkList = warnStrategyCheckMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(checkList)) {
                log.info("checkId:{}为已有策略,该策略状态并非审核不通过,无法提交审核", request.getCheckId());
                throw new BizException("该策略状态并非审核不通过,无法提交审核");
            }
        } else {
            //新增策略校验, 当前诉求状态已改变,
            QueryWrapper<WarnStrategyCheck> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(WarnStrategyCheck::getId, request.getCheckId())
                    .eq(WarnStrategyCheck::getIsDeleted, Constants.IS_DELETED_FALSE)
                    .ne(WarnStrategyCheck::getCheckStatus, 1) //非取消审核状态
                    .eq(WarnStrategyCheck::getSpId, spId);
            List<WarnStrategyCheck> checkList = warnStrategyCheckMapper.selectList(queryWrapper);
            if (!checkList.isEmpty()) {
                log.info("checkId:{}为新增策略,该策略状态并非审核不通过,无法提交审核", request.getCheckId());
                throw new BizException("该策略状态并非审核不通过,无法提交审核");

            }
        }

        warnStrategyService.checkRule(request);
        List<WarnStrategy> warnStrategies = warnStrategyService.queryStrategy(request, spId, request.getId());
        if (CollectionUtil.isNotEmpty(warnStrategies)) {
            //判断 策略是否是冗余
            for (WarnStrategy strategy : warnStrategies) {
                String[] objList = strategy.getStrategyObjValues().split(WarnStrategyCheckServiceImpl.split);
                String[] list = request.getStrategyObjValues().split(WarnStrategyCheckServiceImpl.split);
                for (String obj : list) {
                    if (Arrays.asList(objList).contains(obj)) {
                        throw new BizException("客户已绑定报警规则");
                    }
                }
            }
        }

        //更新 策略诉求的策略内容和状态

        WarnStrategyCheck warnStrategyCheck = new WarnStrategyCheck();
        warnStrategyCheck.setId(request.getCheckId());
        warnStrategyCheck.setCheckStatus(0); //待审核
        warnStrategyCheck.setApplicationTime(DateUtil.format(new Date(), format));
        warnStrategyCheck.setEnterpriseName(request.getEnterpriseName());
        warnStrategyCheck.setHighReport(request.getHighReport());
        warnStrategyCheck.setLowReport(request.getLowReport());
        warnStrategyCheck.setRuleJsonData(JSONObject.toJSONString(request));
        warnStrategyCheck.setRuleName(request.getRuleName());
        warnStrategyCheck.setStrategyObjValues(request.getStrategyObjValues());
        warnStrategyCheck.setSubmitPersonCode(ApplicationUtils.getWorkingUser().getUsername());
        warnStrategyCheck.setSubmitPersonName(ApplicationUtils.getWorkingUser().getName());
        warnStrategyCheck.setSubmitPersonPhone(ApplicationUtils.getWorkingUser().getPhone());
        warnStrategyCheck.setStrategyEquipment(0);
        warnStrategyCheck.setStrategyObj(request.getStrategyObj());

        warnStrategyCheckMapper.updateById(warnStrategyCheck);

    }

    @Override
    public cn.hutool.json.JSONObject getChildSpId(String spId) {
        if (StringUtils.isEmpty(spId)) {
            spId = ApplicationUtils.getWorkingSpId();
        }
        cn.hutool.json.JSONObject jsonObject = vccAuthoritiesProvider.getChildSpId(spId);
        if (jsonObject != null) log.info(jsonObject.toString());
        return jsonObject;
    }
}
